package com.mask.im.business.service.impl;

import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mask.im.business.model.entity.*;
import com.mask.im.business.common.exception.BusinessException;
import com.mask.im.business.model.entity.chat.Friendships;
import com.mask.im.business.model.entity.chat.IMFriendChatMessageDO;
import com.mask.im.business.model.vo.FriendDetailVO;
import com.mask.im.business.common.model.PageResult;
import com.mask.im.business.model.vo.IMFriendVO;
import com.mask.im.business.common.model.RestResponse;
import com.mask.im.business.service.FriendshipsService;
import com.mask.im.business.mapper.IMFriendRelationMapper;
import com.mask.im.business.service.IMGroupChatService;
import com.mask.im.business.common.util.EmailUtil;
import com.mask.im.business.common.util.MaskIMSecurityUtils;
import com.mask.im.business.common.util.PageUtil;
import com.mask.im.business.common.constant.CommonConstant;
import com.mask.im.business.mapper.*;
import com.mask.im.business.model.dto.*;
import com.mask.token.util.MaskSecurityUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import static com.mask.im.business.common.constant.CommonConstant.TRUE;


@Service
public class FriendshipsServiceImpl extends ServiceImpl<FriendshipsMapper, Friendships> implements FriendshipsService {

    @Value("chat.url")
    public String chatUrl;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserAuthMapper userAuthMapper;

    @Autowired
    private IMFriendGroupsMapper IMFriendGroupsMapper;

    @Autowired
    private IMFriendChatMessageMapper IMFriendChatMessageMapper;

    @Autowired
    private UserLabelMapper userLabelMapper;
    @Autowired
    private IMFriendRelationMapper friendRelationMapper;

    @Autowired
    private IMGroupChatService groupChatService;

    @Autowired
    private EmailUtil emailUtil;

    @SneakyThrows
    @Override
    public RestResponse<List<FriendGroupsSortDTO>> getFriendships(String type, String remark, String username) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        if (type.equals("0")) {
            return getGroupShow(remark, userId);
        } else if (type.equals("1")) {
            return getAllShow(remark, userId);
        } else {
            return friendDetail(userId);
        }
    }



    @SneakyThrows
    @Override
    public RestResponse<List<FriendGroupsSortDTO>> getFriendships1(String type, String remark, String username) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        if (type.equals("0")) {
            return getGroupShow(remark, userId);
        } else if (type.equals("1")) {
            return getAllShow(remark, userId);
        } else {
            return friendDetail(userId);
        }
    }

    @SneakyThrows
    private RestResponse<List<FriendGroupsSortDTO>> friendDetail(Long userId) {
        CompletableFuture<Map<String, List<FriendshipsDTO>>> listCompletableFuture = CompletableFuture.supplyAsync(() -> {
            List<FriendshipsDTO> groupChats = groupChatService.getGroupChat(userId);
            List<FriendshipsDTO> friendships = this.baseMapper.getFromFriendships(userId);
            ArrayList<FriendshipsDTO> friendshipsDTOS = new ArrayList<>();
            friendshipsDTOS.addAll(groupChats);
            friendshipsDTOS.addAll(friendships);
            Set<String> userIds = ChannelServiceImpl.userIdChannel.keySet();
            List<FriendshipsDTO> friendshipsDTOList = friendshipsDTOS.stream()
                    // 排序逻辑：置顶消息放最前，非置顶按最新时间倒序（LocalDateTime 替换为 Date）
                    .sorted(Comparator.comparing(
                            (FriendshipsDTO item) -> {
                                // 核心替换：置顶消息用 Date 最大值（对应原 LocalDateTime.MAX），非置顶用 latestTime
                                if (item.getIsTop() != null && item.getIsTop() == 1) {
                                    // Date 最大值：Java 中 Date 底层是毫秒时间戳，最大值为 Long.MAX_VALUE 对应的 Date
                                    return new Date(Long.MAX_VALUE);
                                } else {
                                    // 非置顶：直接使用最新消息时间（已改为 Date 类型）
                                    return item.getLatestTime();
                                }
                            }
                    ).reversed())
                    .peek(item -> {
                        if (Objects.nonNull(item.getFriendId())) {
                            Integer friendId = item.getFriendId();
                            item.setType(1);//这里的1表示为单聊 0表示群聊
                            if (userIds.contains(friendId.toString())) {
                                item.setIsActive(1);
                            } else {
                                item.setIsActive(0);
                            }
                        } else {
                            item.setGroupName("群聊");
                            item.setType(0);
                        }
                    })
                    .collect(Collectors.toList());
            return friendshipsDTOList.stream()
                    .filter(item -> item.getGroupName() != null)
                    .collect(Collectors.groupingBy(
                            FriendshipsDTO::getGroupName));
        });

        CompletableFuture<List<FriendGroupsSortDTO>> friendGroupsSort =
                CompletableFuture.supplyAsync(() -> IMFriendGroupsMapper.getFriendGroupsSort(userId));
        CompletableFuture.allOf(listCompletableFuture, friendGroupsSort);
        FriendGroupsSortDTO sortDTO = new FriendGroupsSortDTO();
        sortDTO.setGroupName("群聊");

        Map<String, List<FriendshipsDTO>> stringListMap = listCompletableFuture.get();

        List<FriendGroupsSortDTO> friendGroupsSortDTOS = friendGroupsSort.get();

        friendGroupsSortDTOS.add(sortDTO);
        List<FriendGroupsSortDTO> friendGroupsSortDTOList = new ArrayList<>();
        friendGroupsSortDTOS
                .forEach(item -> {
                    if (Objects.nonNull(stringListMap.get(item.getGroupName()))) {
                        FriendGroupsSortDTO groupsSortDTO = new FriendGroupsSortDTO();
                        groupsSortDTO.setGroupName(item.getGroupName());
                        groupsSortDTO.setFriendshipsDTOS(stringListMap.get(item.getGroupName()));
                        friendGroupsSortDTOList.add(groupsSortDTO);
                    }
                });
        return RestResponse.ok(friendGroupsSortDTOList);
    }

    private RestResponse<Map<String, List<IMFriendVO>>> friendList(Long userId) {
        List<IMFriendVO> friendList = friendRelationMapper.getFriendList(userId);
        //获取所有在线用户
        Set<String> userIds = ChannelServiceImpl.userIdChannel.keySet();
        if (null != friendList && !friendList.isEmpty()) {
            //封装是否在线
            Map<String, List<IMFriendVO>> objectMap = friendList.stream().peek(
                    item -> {
                        Long friendId = item.getFriendId();
                        if (userIds.contains(friendId.toString())) {
                            item.setIsOnline(1);
                        } else {
                            item.setIsOnline(0);
                        }
                        if (org.apache.commons.lang3.StringUtils.isBlank(item.getGroupName())) {
                            item.setGroupName("好友");
                        }
                    }
            ).collect(Collectors.groupingBy(IMFriendVO::getGroupName, Collectors.toList()));
            return RestResponse.ok(objectMap);
        }
        return RestResponse.ok();
    }

    @SneakyThrows
    private RestResponse<List<FriendGroupsSortDTO>> getAllShow(String remark, Long userId) {
        CompletableFuture<List<FriendshipsDTO>> listCompletableFuture = CompletableFuture.supplyAsync(() -> {
            List<FriendshipsDTO> groupChats = groupChatService.getGroupChat(userId);
            List<FriendshipsDTO> friendships = this.baseMapper.getFromFriendships(userId);
            List<FriendshipsDTO> friendshipsDTOS = new ArrayList<>();
            friendshipsDTOS.addAll(groupChats);
            friendshipsDTOS.addAll(friendships);
            Set<String> userIds = ChannelServiceImpl.userIdChannel.keySet();
            return friendshipsDTOS.stream()
                    .filter(item -> StringUtils.isEmpty(remark) || remark.equals(item.getRemark()))
                    // 排序逻辑：置顶消息放最前，非置顶按最新时间倒序（LocalDateTime 替换为 Date）
                    .sorted(Comparator.comparing(
                            (FriendshipsDTO item) -> {
                                // 核心替换：置顶消息用 Date 最大值（对应原 LocalDateTime.MAX），非置顶用 latestTime
                                if (item.getIsTop() != null && item.getIsTop() == 1) {
                                    // Date 最大值：Java 中 Date 底层是毫秒时间戳，最大值为 Long.MAX_VALUE 对应的 Date
                                    return new Date(Long.MAX_VALUE);
                                } else {
                                    // 非置顶：直接使用最新消息时间（已改为 Date 类型）
                                    return item.getLatestTime();
                                }
                            }
                    ).reversed())
                    .peek(item -> {
                        if (Objects.nonNull(item.getFriendId())) {
                            Integer friendId = item.getFriendId();
                            item.setType(1);//这里的1表示为单聊 0表示群聊
                            if (userIds.contains(friendId.toString())) {
                                item.setIsActive(1);
                            } else {
                                item.setIsActive(0);
                            }
                        } else {
                            item.setType(0);
                        }
                    })
                    .collect(Collectors.toList());
        });
        FriendGroupsSortDTO friendGroupsSortDTO = new FriendGroupsSortDTO();
        friendGroupsSortDTO.setGroupName(null);
        friendGroupsSortDTO.setFriendshipsDTOS(listCompletableFuture.get());
        return RestResponse.ok(Collections.singletonList(friendGroupsSortDTO));
    }

    public RestResponse<List<FriendGroupsSortDTO>> getGroupShow(String remark, Long userId) throws InterruptedException, java.util.concurrent.ExecutionException {
        CompletableFuture<Map<String, List<FriendshipsDTO>>> completableFuture = CompletableFuture.supplyAsync(() -> {
            List<FriendshipsDTO> friendships = this.baseMapper.getFromFriendships(userId);
            Set<String> userIds = ChannelServiceImpl.userIdChannel.keySet();
            List<FriendshipsDTO> collect = friendships.stream()
                    .filter(item -> StringUtils.isEmpty(remark) || remark.equals(item.getRemark()))
                    // 排序逻辑：置顶消息放最前，非置顶按最新时间倒序（LocalDateTime 替换为 Date）
                    .sorted(Comparator.comparing(
                            (FriendshipsDTO item) -> {
                                // 核心替换：置顶消息用 Date 最大值（对应原 LocalDateTime.MAX），非置顶用 latestTime
                                if (item.getIsTop() != null && item.getIsTop() == 1) {
                                    // Date 最大值：Java 中 Date 底层是毫秒时间戳，最大值为 Long.MAX_VALUE 对应的 Date
                                    return new Date(Long.MAX_VALUE);
                                } else {
                                    // 非置顶：直接使用最新消息时间（已改为 Date 类型）
                                    return item.getLatestTime();
                                }
                            }
                    ).reversed())
                    .peek(item -> {
                        Integer friendId = item.getFriendId();
                        item.setType(1); //这里的1表示为单聊 0表示群聊
                        if (userIds.contains(friendId.toString())) {
                            item.setIsActive(1);
                        } else {
                            item.setIsActive(0);
                        }
                    })
                    .collect(Collectors.toList());
            return collect.stream()
                    .filter(item -> item.getGroupName() != null)
                    .collect(Collectors.groupingBy(
                            FriendshipsDTO::getGroupName));
        });
        CompletableFuture<List<FriendGroupsSortDTO>> friendGroupsSort =
                CompletableFuture.supplyAsync(() -> IMFriendGroupsMapper.getFriendGroupsSort(userId));

        //等待两个任务完成
        CompletableFuture.allOf(completableFuture, friendGroupsSort);
        Map<String, List<FriendshipsDTO>> stringListMap = completableFuture.get();

        List<FriendGroupsSortDTO> groupsSortDTOS = friendGroupsSort.get().stream()
                .peek(item -> {
                    if (Objects.nonNull(stringListMap.get(item.getGroupName()))) {
                        item.setFriendshipsDTOS(stringListMap.get(item.getGroupName()));
                    } else {
                        item.setFriendshipsDTOS(new ArrayList<>());
                    }

                })
                .collect(Collectors.toList());
        return RestResponse.ok(groupsSortDTOS);
    }

    @Override
    public List<String> byUserId(String userId) {
        List<Friendships> friendships = this.baseMapper.selectList(new LambdaQueryWrapper<Friendships>()
                .select(Friendships::getTwoUserId)
                .eq(Friendships::getOneUserId, userId));
        return friendships.stream().map(item -> item.getTwoUserId().toString())
                .collect(Collectors.toList());
    }

    @Override
    public FriendChatMessageDTO getChatMessageDTO(IMFriendChatMessageDO imFriendChatMessage) {
        Long userId = MaskIMSecurityUtils.getUseLongId();
        UserInfo userInfo = userInfoMapper.selectById(userId);
        FriendChatMessageDTO friendChatMessageDTO = this.baseMapper.getChatMessageDTO(imFriendChatMessage.getId(), userId, imFriendChatMessage.getReceiverId());
        friendChatMessageDTO.setSenderId(userId);
        friendChatMessageDTO.setReceiveId(imFriendChatMessage.getReceiverId());
        friendChatMessageDTO.setSenderAvatar(userInfo.getAvatar());
        friendChatMessageDTO.setIsMyselfMsg(imFriendChatMessage.getSenderId().equals(userId));
        friendChatMessageDTO.setSenderName(userInfo.getNickName());
        return friendChatMessageDTO;
    }

    @Override
    public RestResponse<List<FriendshipsDTO>> remoteFriendships(String keyword) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        if (!StringUtils.isEmpty(keyword)) {
            List<FriendshipsDTO> friendshipsDTOS = this.baseMapper.remoteFriendships(userId, keyword);
            return RestResponse.ok(friendshipsDTOS);
        }
        return RestResponse.ok(new ArrayList<>());
    }

    @Override
    public RestResponse<Integer> applyFriendCount() {
        Integer userId = MaskIMSecurityUtils.getUserId();
        Integer count = this.baseMapper.selectCount(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getIsFriends, 0));
        return RestResponse.ok(count);
    }

    @Override
    public RestResponse<List<FriendshipsDTO>> allFriendRequest() {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        List<FriendshipsDTO> friendshipsDTOS = this.baseMapper.allFriendRequest(userId,
                PageUtil.getCurrentPage(), PageUtil.getSize());
        return RestResponse.ok(friendshipsDTOS);
    }

    @Override
    public RestResponse<?> searchUser(String keyword) {
        SearchUserDTO searchUserDTO = null;
        boolean flag = true;
        if (Validator.isMobile(keyword)) {
            //手机搜索
            UserAuth userAuth = userAuthMapper
                    .selectOne(new LambdaQueryWrapper<UserAuth>().eq(UserAuth::getPhone, keyword));
            if (Objects.nonNull(userAuth)) {
                UserInfo userInfo = userInfoMapper.selectById(userAuth.getUserInfoId());
                searchUserDTO = buildSearchUserDTO(userInfo);
            }

        } else if (Validator.isEmail(keyword)) {
            //邮箱搜索
            UserAuth userAuth = userAuthMapper
                    .selectOne(new LambdaQueryWrapper<UserAuth>().eq(UserAuth::getEmail, keyword));
            if (Objects.nonNull(userAuth)) {
                UserInfo userInfo = userInfoMapper.selectById(userAuth.getUserInfoId());
                searchUserDTO = buildSearchUserDTO(userInfo);
            }
        } else {
            //登入名搜索
            flag = false;
            UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                    .eq(UserInfo::getUsername, keyword));
            if (Objects.nonNull(userInfo)) {
                searchUserDTO = buildSearchUserDTO(userInfo);
            }
        }
        //防止登入名为手机号或者邮箱号
        if (!flag) {
            UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                    .eq(UserInfo::getUsername, keyword));
            searchUserDTO = buildSearchUserDTO(userInfo);
        }
        if (searchUserDTO != null && Objects.nonNull(searchUserDTO.getUserInfoId())) {
            Long userId = MaskSecurityUtil.getCurrentUserId();
            //判断是否为自己
            if (userId.equals(searchUserDTO.getUserInfoId())) {
                return RestResponse.ok();
            }

            //判断是否为自己好友，如果是则进行相关字段填充
            Friendships myFriendships = this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                    .eq(Friendships::getOneUserId, userId)
                    .eq(Friendships::getTwoUserId, searchUserDTO.getUserInfoId()));

            Friendships otherFriendships = this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                    .eq(Friendships::getOneUserId, searchUserDTO.getUserInfoId())
                    .eq(Friendships::getTwoUserId, userId));

            //用于判断是否两人为好友或者为黑名单
            if (Objects.nonNull(otherFriendships) && Objects.nonNull(myFriendships)) {
                if (otherFriendships.getIsFriends().equals(CommonConstant.IS_FRIEND) &&
                        myFriendships.getIsFriends().equals(CommonConstant.IS_FRIEND)) {
                    searchUserDTO.setFriendId(myFriendships.getId());
                    searchUserDTO.setRemark(myFriendships.getRemark());
                    searchUserDTO.setIsFriend(CommonConstant.IS_FRIEND);
                } else if (!otherFriendships.getIsFriends().equals(CommonConstant.IS_FRIEND)) {
                    if (otherFriendships.getIsFriends().equals(CommonConstant.NOT_FRIEND)) {
                        searchUserDTO.setFriendId(myFriendships.getId());
                        searchUserDTO.setRemark(myFriendships.getRemark());
                        searchUserDTO.setIsFriend(CommonConstant.NOT_FRIEND);
                    } else if (otherFriendships.getIsFriends().equals(CommonConstant.BLACKLIST)) {
                        searchUserDTO.setRemark(myFriendships.getRemark());
                        searchUserDTO.setIsFriend(CommonConstant.BLACKLIST);
                    } else {
                        searchUserDTO.setIsFriend(otherFriendships.getIsFriends());
                    }

                } else if (!myFriendships.getIsFriends().equals(CommonConstant.IS_FRIEND)) {
                    searchUserDTO.setRemark(myFriendships.getRemark());
                    searchUserDTO.setIsFriend(myFriendships.getIsFriends());
                }
            } else if (Objects.nonNull(myFriendships)) {
                searchUserDTO.setFriendId(myFriendships.getId());
                searchUserDTO.setRemark(myFriendships.getRemark());
                searchUserDTO.setIsFriend(CommonConstant.NOT_ADD_FRIEND);

            } else if (Objects.nonNull(otherFriendships)) {
                searchUserDTO.setIsFriend(otherFriendships.getIsFriends());
            } else {
                searchUserDTO.setIsFriend(CommonConstant.NOT_ADD_FRIEND);
            }

        }
        return RestResponse.ok(searchUserDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteFriend(Long friendId) {
        Long userId = MaskSecurityUtil.getCurrentUserId();

        Friendships friendships = this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getTwoUserId, friendId)
                .eq(Friendships::getIsFriends, CommonConstant.IS_FRIEND));

        if (Objects.nonNull(friendships)) {
            //删除好友关系
            this.baseMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                    .set(Friendships::getIsDelete, 1) //这里1表示删除
                    .set(Friendships::getIsFriends, CommonConstant.NOT_ADD_FRIEND)
                    .eq(Friendships::getOneUserId, userId)
                    .eq(Friendships::getTwoUserId, friendId));
            //删除聊天记录
            IMFriendChatMessageMapper.update(null, new LambdaUpdateWrapper<IMFriendChatMessageDO>()
                    .set(IMFriendChatMessageDO::getSenderDeleted, 1)
                    .eq(IMFriendChatMessageDO::getSenderId, userId)
                    .eq(IMFriendChatMessageDO::getReceiverId, friendId));
            IMFriendChatMessageMapper.update(null, new LambdaUpdateWrapper<IMFriendChatMessageDO>()
                    .set(IMFriendChatMessageDO::getReceiverDeleted, 1)
                    .eq(IMFriendChatMessageDO::getSenderId, friendId)
                    .eq(IMFriendChatMessageDO::getReceiverDeleted, userId));
        }
    }

    @Override
    public FriendshipsDTO getFriendshipsDTO(Long myUserInfoId, Long otherUserInfoId) {
        return this.baseMapper.getFriendships(myUserInfoId, otherUserInfoId);
    }

    @Override
    public RestResponse<?> getUserById(Long id) {
        UserAuth userAuth = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>()
                .eq(UserAuth::getUserInfoId, id));
        if (Objects.isNull(userAuth)) {
            throw new BusinessException("用户不存在");
        }
        if (userAuth.getEmail() != null) {
            return searchUser(userAuth.getEmail());
        } else if (userAuth.getPhone() != null) {
            return searchUser(userAuth.getPhone());
        } else {
            return searchUser(userAuth.getUsername());
        }
    }

    @Override
    public RestResponse<String> addBlacklist(Long friendId) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        Friendships friendships = getFriendMessage(friendId, userId);
        if (Objects.isNull(friendships) || (!friendships.getIsFriends().equals(CommonConstant.IS_FRIEND) && !friendships.getIsFriends().equals(CommonConstant.BLACKLIST))) {
            throw new BusinessException("对方不是你好友");
        }

        if (!friendships.getIsFriends().equals(CommonConstant.BLACKLIST)) {
            this.baseMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                    .set(Friendships::getIsFriends, CommonConstant.BLACKLIST)
                    .eq(Friendships::getOneUserId, userId)
                    .eq(Friendships::getTwoUserId, friendId));
        }
        return RestResponse.ok();
    }

    @Override
    public RestResponse<FriendDetailDTO> getFriendById(Long friendId) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        checkIsFriend(userId, friendId);

        FriendDetailDTO friendById = this.baseMapper.getFriendById(userId, friendId);
        return RestResponse.ok(friendById);
    }

    @Override
    @Transactional
    public RestResponse<FriendDetailDTO> updateFriendDetail(FriendDetailVO friendDetailVO) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        checkIsFriend(userId, friendDetailVO.getFriendId());
        String label = StringUtils.join(friendDetailVO.getLabel(), ",");
        this.baseMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                .set(Objects.nonNull(friendDetailVO.getRemark()), Friendships::getRemark, friendDetailVO.getRemark())
                .set(Objects.nonNull(label), Friendships::getLabel, label)
                .set(Objects.nonNull(friendDetailVO.getDescription()), Friendships::getDescription, friendDetailVO.getDescription())
                .eq(Friendships::getOneUserId, userId).eq(Friendships::getTwoUserId, friendDetailVO.getFriendId()));
        userLabelMapper.delete(new LambdaQueryWrapper<UserLabel>()
                .eq(UserLabel::getUserInfoId, userId));
        UserLabel userLabel = UserLabel.builder().userInfoId(userId).labelName(label).build();
        userLabelMapper.insert(userLabel);
        return getFriendById(friendDetailVO.getFriendId());
    }

    @Override
    public RestResponse<String> updateStar(Long twoUserId, Integer isStar) {
        Integer oneUserId = MaskIMSecurityUtils.getUserId();
        this.baseMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                .set(Friendships::getIsStar, isStar)
                .eq(Friendships::getOneUserId, oneUserId)
                .eq(Friendships::getTwoUserId, twoUserId));
        return RestResponse.ok();
    }

    @Override
    public RestResponse<Integer> getInsertLocation() {
        Integer oneUserId = MaskIMSecurityUtils.getUserId();
        QueryWrapper<Friendships> wrapper = new QueryWrapper<>();
        wrapper.eq("one_user_id", oneUserId);
        wrapper.eq("is_friends", CommonConstant.IS_FRIEND);
        wrapper.and(item -> item.eq("is_top", 1));

        Integer count = this.baseMapper.selectCount(wrapper);
        return RestResponse.ok(count);
    }

    @SneakyThrows
    @Override
    public PageResult<FriendsBlacklistDTO> getBlacklistFriend(String remark) {
        Long oneUserId = MaskSecurityUtil.getCurrentUserId();
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> this.baseMapper.selectCount(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, oneUserId)
                .like(Friendships::getRemark, remark)
                .eq(Friendships::getIsFriends, CommonConstant.BLACKLIST)));

        List<FriendsBlacklistDTO> friendsBlacklistDTOS =
                this.baseMapper.getBlacklistFriend(oneUserId, PageUtil.getCurrentPage(), PageUtil.getSize(), remark);
        return PageResult.<FriendsBlacklistDTO>builder()
                .data(friendsBlacklistDTOS)
                .code(200)
                .total(future.get()).build();
    }

    @Override
    public void cancelBlacklistFriend(String friendIds) {
//		Integer oneUserId = MaskIMSecurityUtils.getUserId();
        String[] split = friendIds.split(",");
        for (String id : split) {
            this.baseMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                    .set(Friendships::getIsFriends, CommonConstant.IS_FRIEND)
                    .eq(Friendships::getId, Integer.valueOf(id)));
        }
    }

    @Override
    public void addUnreadCount(Long friendId) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        this.baseMapper.updateUnreadCount(userId, friendId);
    }

    @Override
    public void clearUnreadCount(Long friendId) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        this.baseMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                .set(Friendships::getUnreadCount, 0)
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getTwoUserId, friendId));
    }

    @Override
    public RestResponse<SidewaysStatusDTO> getSidewaysStatus(Long friendId) {
        Long userInfoId = MaskSecurityUtil.getCurrentUserId();
        SidewaysStatusDTO statusDTO = this.baseMapper.getSidewaysStatus(userInfoId, friendId);
        return RestResponse.ok(statusDTO);
    }

    @Override
    public void isTop(Long friendId, Integer status) {
        Integer userInfoId = MaskIMSecurityUtils.getUserId();
        this.update(null, new LambdaUpdateWrapper<Friendships>()
                .set(Friendships::getIsTop, status)
                .eq(Friendships::getOneUserId, userInfoId)
                .eq(Friendships::getTwoUserId, friendId));
    }

    @Override
    public void rejectAddFriend(Long friendId) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        this.baseMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                .set(Friendships::getIsFriends, CommonConstant.REJECT)
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getTwoUserId, friendId)
                .eq(Friendships::getIsFriends, CommonConstant.NOT_FRIEND));
    }

    @Override
    public void notifyFriendOnline(NotifyFriend notifyFriend) {
        Integer userInfoId = MaskIMSecurityUtils.getUserId();
        Friendships friendships1 = this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userInfoId)
                .eq(Friendships::getTwoUserId, notifyFriend.getFriendId())
                .eq(Friendships::getIsFriends, CommonConstant.IS_FRIEND));
        if (Objects.isNull(friendships1)) {
            throw new BusinessException("对方不是您的好友");
        }
        UserAuth userAuth = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>()
                .select(UserAuth::getEmail)
                .eq(UserAuth::getUserInfoId, notifyFriend.getFriendId()));
        if (userAuth == null || StringUtils.isEmpty(userAuth.getEmail()) || !Validator.isEmail(userAuth.getEmail())) {
            throw new BusinessException("抱歉！对方暂未留存邮箱，无法进行通知");
        }
        Friendships friendships2 = this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, notifyFriend.getFriendId())
                .eq(Friendships::getTwoUserId, userInfoId)
                .eq(Friendships::getIsFriends, CommonConstant.IS_FRIEND));
        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分"));
        Map<String, Object> map = new HashMap<>();
        map.put("content", "您的好友<span style=\"color:red\">" + friendships2.getRemark() + "</span>于" + format + "提醒您上线<a href=\"https://www.pengzhenggao.top\">即时聊天系统</a>与他（她）进行对话。");
        EmailDTO emailDTO = EmailDTO.builder()
                .template("common.html")
                .email(userAuth.getEmail())
                .subject("上线通知")
                .commentMap(map).build();
        CompletableFuture.runAsync(() -> emailUtil.sendHtmlMail(emailDTO));

    }

    @Override
    public RestResponse<List<GroupChatShowDTO>> buildGroupChatShow(String keyword) {
        Long userInfoId = MaskSecurityUtil.getCurrentUserId();
        List<GroupChatShowDTO> groupChatShowDTOS = this.baseMapper.buildGroupChatShow(userInfoId, keyword);
        return RestResponse.ok(groupChatShowDTOS);
    }

    @Override
    public RestResponse<List<PersonalDTO>> getRecommendFriends(Long userInfoId, String keyword) {
        Long myId = MaskSecurityUtil.getCurrentUserId();
        List<PersonalDTO> personalDTOList = this.baseMapper.getRecommendFriends(keyword, userInfoId, myId);
        return RestResponse.ok(personalDTOList);
    }

    @Override
    public Friendships confirmIsFriend(Long myId, Long userInfo) {
        return this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, myId)
                .eq(Friendships::getTwoUserId, userInfo));
    }

    @Override
    public RestResponse<TransferMessageDTO> transferMessage(Long friendId) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        Friendships friendships = this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getTwoUserId, friendId));
        UserInfo userInfo = userInfoMapper.selectById(friendId);
        UserAuth userAuth = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>()
                .eq(UserAuth::getUserInfoId, userId));
        TransferMessageDTO transferMessageDTO = new TransferMessageDTO();
        transferMessageDTO.setAvatar(userInfo.getAvatar());
        transferMessageDTO.setUsername(privacyUsername(userInfo.getUsername()));
        transferMessageDTO.setRemark(friendships.getRemark());
        transferMessageDTO.setContact(privacyContacts(userAuth.getEmail() != null ? userAuth.getEmail() : userAuth.getPhone()));
        return RestResponse.ok(transferMessageDTO);
    }

    public void checkIsFriend(Long userId, Long friendId) {
        Friendships otherFriendMessage = getFriendMessage(userId, friendId);
        if (null == otherFriendMessage || (otherFriendMessage.getIsFriends() == 0 || otherFriendMessage.getIsFriends() == 2)) {
            throw new BusinessException("对方还不是您的好友，无法查看对方信息");
        }
        Friendships myFriendMessage = getFriendMessage(friendId, userId);
        if (null == myFriendMessage || (myFriendMessage.getIsFriends() == 0 || myFriendMessage.getIsFriends() == 2)) {
            throw new BusinessException("对方还不是您的好友，无法查看对方信息");
        }
    }

    private String privacyUsername(String username) {
        if (username == null || username.length() == 0) {
            return " ";
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < username.length() - 1; i++) {
            stringBuilder.append("*");
        }
        stringBuilder.append(username.charAt(username.length() - 1));
        return stringBuilder.toString();
    }

    private String privacyContacts(String contacts) {
        if (contacts == null || contacts.length() == 0) {
            return " ";
        }
        if (Validator.isMobile(contacts)) {
            return contacts.substring(0, 3) + "****" + contacts.substring(7);
        } else if (Validator.isEmail(contacts)) {
            String[] parts = contacts.split("@");
            if (parts.length != 2) {
                return contacts; // 或者处理错误情况
            }
            String username = parts[0];
            if (username.length() <= 2) {
                return contacts; // 或者处理太短的用户名情况
            }
            return username.charAt(0) + "****" + username.charAt(username.length() - 1) + "@" + parts[1];
        }
        return " ";
    }

    public Friendships getFriendMessage(Long friendId, Long userId) {
        return this.baseMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getTwoUserId, friendId));
    }

    public SearchUserDTO buildSearchUserDTO(UserInfo userInfo) {
        SearchUserDTO searchUserDTO = new SearchUserDTO();
        if (Objects.isNull(userInfo) || !userInfo.getAllowSearching().equals(TRUE)) {
            return searchUserDTO;
        }
        searchUserDTO.setAvatar(userInfo.getAvatar());
        searchUserDTO.setGender(userInfo.getGender());
        searchUserDTO.setNickName(userInfo.getNickName());
        searchUserDTO.setUserInfoId(userInfo.getId());
        searchUserDTO.setUsername(userInfo.getUsername() == null ? "未知" : userInfo.getUsername());
        searchUserDTO.setAddress(userInfo.getAddress() == null ? "未知" : userInfo.getAddress());
        return searchUserDTO;
    }
}

